/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.asu.cse360.service.client;

import edu.asu.cse360.model.Chef;
import edu.asu.cse360.model.CustomerSession;
import edu.asu.cse360.model.Employee;
import edu.asu.cse360.model.ItemOrder;
import edu.asu.cse360.model.Manager;
import edu.asu.cse360.model.MenuItem;
import edu.asu.cse360.model.OrderStatus;
import edu.asu.cse360.model.Restaurant;
import edu.asu.cse360.model.Table;
import edu.asu.cse360.model.WaitPerson;
import edu.asu.cse360.service.ItemOrderService;
import edu.asu.cse360.service.OrderStatusService;
import edu.asu.cse360.util.EmployeeVisitor;
import java.util.ArrayList;
import java.util.List;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;


public class ClientItemOrderService implements ItemOrderService{
    private EmployeeVisitor getCurrentOrdersVisitor(){
        return new EmployeeVisitor(){
            @Override
            public Object visit(Manager manager) {
              return getCurrentOrders(manager);
            }

            @Override
            public Object visit(WaitPerson waitPerson) {
              return getCurrentOrders(waitPerson);
            }

            @Override
            public Object visit(Chef chef) {
              return getCurrentOrders(chef);
            }
        };
    }


    @Autowired
    private List<ItemOrder> itemOrders;

    private OrderStatusService orderStatusSvc;

    public ClientItemOrderService(OrderStatusService orderStatusService) {
        this.orderStatusSvc = orderStatusService;
    }

    @Override
    public List<ItemOrder> getCurrentOrders(Employee employee) {
       return (List<ItemOrder>) employee.accept(getCurrentOrdersVisitor());
    }

    private List<ItemOrder> getCurrentOrders(Manager manager){
        return itemOrders;
    }

    private List<ItemOrder> getCurrentOrders(WaitPerson waitPerson){
        List<OrderStatus> allowedStatuses = orderStatusSvc.getStatusViewableByWaitPerson();
        return getOrdersMatchingStatuses(allowedStatuses);
    }

    private List<ItemOrder> getCurrentOrders(Chef chef){
        List<OrderStatus> allowedStatuses = orderStatusSvc.getStatusViewableByChef();
        return getOrdersMatchingStatuses(allowedStatuses);
    }

    private List<ItemOrder> getOrdersMatchingStatuses(List<OrderStatus> statuses) {
        List<ItemOrder> filteredOrders = new ArrayList<ItemOrder>();
        for(ItemOrder itemOrder: itemOrders){
            if(statuses.contains(itemOrder.getStatus())){
                filteredOrders.add(itemOrder);
            }
        }
        return filteredOrders;
    }

    @Override
    public ItemOrder save(ItemOrder itemOrder) {
        if(!itemOrders.contains(itemOrder)){
            itemOrders.add(itemOrder);
        }
        return itemOrder;
    }

    @Override
    public ItemOrder setStatus(ItemOrder itemOrder, OrderStatus orderStatus, Employee employee) {
        if(employee instanceof WaitPerson){
            itemOrder.setWaitPerson((WaitPerson) employee);
        }else if(employee instanceof Chef){
            itemOrder.setChef((Chef) employee);
        }
        itemOrder.setStatus(orderStatus);
        return itemOrder;
    }

    @Override
    public List<ItemOrder> getItemOrders(Restaurant restaurant, DateTime start, DateTime end) {
        List<ItemOrder> filteredList = new ArrayList<ItemOrder>();
        for(ItemOrder itemOrder : itemOrders){
            if(itemOrder.getOrderTime().compareTo(start) >= 0 && itemOrder.getOrderTime().compareTo(end) <= 0){
                filteredList.add(itemOrder);
            }
        }
        return filteredList;
    }

    @Override
    public ItemOrder find(Integer id) {
       for(ItemOrder itemOrder : itemOrders){
           if(itemOrder.getId().equals(id)){
               return itemOrder;
           }
       }
       return null;
    }

    @Override
    public List<ItemOrder> getItemOrders(CustomerSession customerSession) {
        return itemOrders;
    }

    @Override
    public void deleteAllTiedToMenuItem(MenuItem menuItem) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public ItemOrder remove(ItemOrder itemOrder) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<ItemOrder> findByWaitPerson(WaitPerson waitPerson) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public List<ItemOrder> findByChef(Chef chef) {
        throw new UnsupportedOperationException("Not supported yet.");
    }


}
